﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using Oscilloscope.Util;

namespace Oscilloscope.ChannelBuffer
{
	// Token: 0x02000017 RID: 23
	internal class FileChannelBuffer : IChannelBuffer, IDisposable
	{
		// Token: 0x060000FA RID: 250 RVA: 0x00008630 File Offset: 0x00006830

		public FileChannelBuffer(string filePath,string strType)
		{

            this.fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.None);
			this.sampleFrenquency = this.ReadUshort(this.fs);
			int num = this.ReadUshort(this.fs);
			int num2 = this.ReadUshort(this.fs);

			if (num2 == 1)
			{
				this.signalType = SignalType.AnalogSigned;
			}
			else if (num2 == 0)
			{
				this.signalType = SignalType.AnalogUnsigned;
			}
			if (num >= 0)
			{
				var typeStrings = strType.Split('$')[0];
				var typeStringDecimalCount = strType.Split('$')[1];
                if (typeStrings == "F32")
				{
                    this.DataType = DataType.浮点;
                    this.referenceValue = (double)((double)num / double.Parse(typeStringDecimalCount));
                    //Console.WriteLine($"当前倍率{typeStringDecimalCount}"+this.referenceValue);

					switch (int.Parse(strType.Split('$')[1]))
					{
						case 0: this.RatioType = SignalRatio.x1;
							break;
                        case 10:
                            this.RatioType = SignalRatio.x10;
                            break;
                        case 100:
                            this.RatioType = SignalRatio.x100;
                            break;
                        case 1000:
                            this.RatioType = SignalRatio.x1k;
                            break;
                        case 10000:
                            this.RatioType = SignalRatio.x10k;
                            break;
                        case 100000:
                            this.RatioType = SignalRatio.x100k;
                            break;
                    }
                }
				else if(typeStrings == "I16")
				{
                    this.DataType = DataType.整;
                    this.referenceValue = (double)((short)num);
                    this.signalType = SignalType.AnalogSigned;
                }
                else if (typeStrings == "U16")
                {
                    this.DataType = DataType.整;
                    this.referenceValue = (double)((ushort)num);
                    this.signalType = SignalType.AnalogUnsigned;
                }
                else if (typeStrings == "MultiBit")
                {
                    this.DataType = DataType.整;
                    this.referenceValue = (double)((ushort)num);
					this.signalType = SignalType.DigitalMultiple;
                }
            }
		}

       


        public double GetTimeInterval()
		{
			if (this.fs == null || this.sampleFrenquency <= 0)
			{
				return 0.0;
			}
			return 1.0 / (double)this.sampleFrenquency;
		}

		public double GetTotalTime()
		{
			if (this.GetTimeInterval() <= 0.0)
			{
				return 0.0;
			}
			double num = (double)((this.fs.Length - (long)FileChannelBuffer.DATA_OFFSET) / 3L - 1L) * this.GetTimeInterval();
			if (num <= 0.0)
			{
				return 0.0;
			}
			return num;
		}

		// Token: 0x060000FD RID: 253 RVA: 0x00008760 File Offset: 0x00006960
		public double GetReferenceValue()
		{
			return this.referenceValue;
		}

		// Token: 0x060000FE RID: 254 RVA: 0x00008768 File Offset: 0x00006968
		public SignalType GetSignalType()
		{
			return this.signalType;
		}

		/// <summary>
		/// 获取buffer内部的数据
		/// </summary>
		/// <param name="startTime"></param>
		/// <param name="endTime"></param>
		/// <param name="buffer"></param>
		/// <param name="offset"></param>
		/// <param name="timeOfFirstData"></param>
		/// <returns></returns>
		/// <exception cref="IndexOutOfRangeException"></exception>
		public int GetData(double startTime, double endTime, ChannelBufferData[] buffer, int offset, ref double timeOfFirstData)
		{
			long num = 0L;
			int dataByteRange = this.GetDataByteRange(startTime, endTime, ref num);
			if (dataByteRange == 0)
			{
				return 0;
			}
			if (offset + dataByteRange > buffer.Length)
			{
				throw new IndexOutOfRangeException();
			}
			this.fs.Position = num;
			for (int i = 0; i < dataByteRange; i++)
			{
				if (this.DataType== DataType.浮点)
				{
                    //修改buffer内的数据
                   var ushortData = (double)((short)this.ReadUshort(this.fs));
					var signalRatio = this.RatioType;
					var sRatio = 0;
                    switch (signalRatio)
                    {
                        case SignalRatio.x1:
                            sRatio = (int)SignalRatio.x1;
                            break;
                        case SignalRatio.x10:
                            sRatio = (int)SignalRatio.x10;
                            break;
                        case SignalRatio.x100:
                            sRatio = (int)SignalRatio.x100;
                            break;
                        case SignalRatio.x1k:
                            sRatio = (int)SignalRatio.x1k;
                            break;
                        case SignalRatio.x10k:
                            sRatio = (int)SignalRatio.x10k;
                            break;
                        case SignalRatio.x100k:
                            sRatio = (int)SignalRatio.x100k;
                            break;
                        default:
                            break;
                    }

                    buffer[i + offset].Data = ushortData/ sRatio;
                }
				else
				{
                    if (this.signalType == SignalType.AnalogSigned)
                    {

                        //修改buffer内的数据
                        buffer[i + offset].Data = (double)((short)this.ReadUshort(this.fs));
                    }
                    else
                    {
                        buffer[i + offset].Data = (double)this.ReadUshort(this.fs);
                    }
                }
				buffer[i + offset].IsValid = this.ReadValidFlag(this.fs);
			}
			timeOfFirstData = (double)((num - (long)FileChannelBuffer.DATA_OFFSET) / 3L) * this.GetTimeInterval();
			return dataByteRange;
		}

		// Token: 0x06000100 RID: 256 RVA: 0x0000882C File Offset: 0x00006A2C
		public int GetDataCount(double startTime, double endTime)
		{
			long num = 0L;
			return this.GetDataByteRange(startTime, endTime, ref num);
		}

		// Token: 0x06000101 RID: 257 RVA: 0x00008848 File Offset: 0x00006A48
		private int GetDataByteRange(double startTime, double endTime, ref long firstDataStartByteIndex)
		{
			if (startTime < 0.0 || endTime < 0.0 || endTime < startTime)
			{
				throw new ArgumentOutOfRangeException();
			}
			if (startTime == endTime || this.GetTotalTime() <= 0.0)
			{
				return 0;
			}
			double integralMultipleOfStepBaseValueOf = InternalUtils.GetIntegralMultipleOfStepBaseValueOf(startTime, this.GetTimeInterval(), false);
			double integralMultipleOfStepBaseValueOf2 = InternalUtils.GetIntegralMultipleOfStepBaseValueOf(endTime, this.GetTimeInterval(), true);
			if (integralMultipleOfStepBaseValueOf > this.GetTotalTime())
			{
				return 0;
			}
			long num = Convert.ToInt64(integralMultipleOfStepBaseValueOf / this.GetTimeInterval());
			long num2 = Convert.ToInt64(integralMultipleOfStepBaseValueOf2 / this.GetTimeInterval());
			long num3 = (long)FileChannelBuffer.DATA_OFFSET + num * 3L;
			long num4;
			for (num4 = num3; num4 >= (long)FileChannelBuffer.DATA_OFFSET; num4 -= 3L)
			{
				this.fs.Position = num4;
				this.ReadUshort(this.fs);
				if (this.ReadValidFlag(this.fs))
				{
					break;
				}
			}
			if (num4 >= (long)FileChannelBuffer.DATA_OFFSET)
			{
				num3 = num4;
			}
			long num5 = (long)FileChannelBuffer.DATA_OFFSET + num2 * 3L;
			if (num5 > this.fs.Length - 3L)
			{
				num5 = this.fs.Length - 3L;
			}
			for (num4 = num5; num4 <= this.fs.Length - 3L; num4 += 3L)
			{
				this.fs.Position = num4;
				this.ReadUshort(this.fs);
				if (this.ReadValidFlag(this.fs))
				{
					break;
				}
			}
			if (num4 <= this.fs.Length - 3L)
			{
				num5 = num4;
			}
			int result = (int)((num5 - num3) / 3L + 1L);
			firstDataStartByteIndex = num3;
			return result;
		}

		// Token: 0x06000102 RID: 258 RVA: 0x000089D3 File Offset: 0x00006BD3
		public void Dispose()
		{
			if (this.fs != null)
			{
				this.fs.Close();
				this.fs.Dispose();
				this.fs = null;
			}
		}

		// Token: 0x06000103 RID: 259 RVA: 0x000089FC File Offset: 0x00006BFC
		private int ReadUshort(FileStream fs)
		{
			if (fs == null)
			{
				throw new ArgumentNullException();
			}
			int num = 0;
			int num2 = fs.ReadByte();
			if (num2 < 0)
			{
				return -1;
			}
			num |= num2;
			num <<= 8;
			num2 = fs.ReadByte();
			if (num2 < 0)
			{
				return -1;
			}
			return num | num2;
		}

		// Token: 0x06000104 RID: 260 RVA: 0x00008A3C File Offset: 0x00006C3C
		private bool ReadValidFlag(FileStream fs)
		{
			if (fs == null)
			{
				throw new ArgumentNullException();
			}
			int num = fs.ReadByte();
			return num > 0;
		}

		// Token: 0x06000105 RID: 261 RVA: 0x00008A60 File Offset: 0x00006C60
		public void AddSampleData(short? data)
		{
		}

		// Token: 0x06000106 RID: 262 RVA: 0x00008A62 File Offset: 0x00006C62
		public IChannelBuffer Copy()
		{
			return this;
		}

		// Token: 0x06000107 RID: 263 RVA: 0x00008A65 File Offset: 0x00006C65
		public void CopyTo(IChannelBuffer desChannelBuffer)
		{
		}

		// Token: 0x04000068 RID: 104
		private static readonly int DATA_OFFSET = 6;

		// Token: 0x04000069 RID: 105
		private FileStream fs;

		// Token: 0x0400006A RID: 106
		private int sampleFrenquency = -1;

		// Token: 0x0400006B RID: 107
		private double referenceValue;

		// Token: 0x0400006C RID: 108
		private SignalType signalType;
		private SignalRatio RatioType;
		private DataType DataType;
	}
}
